package task

import (
	"encoding/json"
	"fmt"
	"github.com/astaxie/beego/logs"
	"io/ioutil"
	"net/http"
	lmodel "payspace/models"
	"time"
)

const (
	baseUrl = "https://api.coinmarketcap.com/v2/ticker/"   // get price api
	url1    = "https://api.coinmarketcap.com/v2/listings/" // token id api
)

var PriceMap = make(map[string]interface{})

func updatePrice() {
	for {
		tokens, err := lmodel.GetSupportedTokens()

		if err != nil {
			logs.Error("query tokens failed:", err)
			time.Sleep(10 * time.Second)
			continue
		}

		// get api token id
	CallTokensApi:
		resp, err := http.Get(url1)
		if err != nil {
			// handle error
			logs.Error("call api failed:", err)
			time.Sleep(10 * time.Second)
			goto CallTokensApi
		}

		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			logs.Error("parse response failed:", err)
			time.Sleep(10 * time.Second)
			goto CallTokensApi
		}

		result := make(map[string]interface{})
		err = json.Unmarshal(body, &result)
		if err != nil {
			logs.Error("parse response failed:", err)
			time.Sleep(10 * time.Second)
			goto CallTokensApi
		}

		resp.Body.Close()

		if result["data"] == nil {
			logs.Error("parse response failed:", err)
			time.Sleep(10 * time.Second)
			goto CallTokensApi
		}

		data := result["data"].([]interface{})

		// get token symbols
		var symbols []string
		for _, token := range tokens {
			symbol := token.Symbol
			symbols = append(symbols, symbol)
		}

		// symbol-id Map
		IdMap := make(map[string]float64)
		IdMap["ETH"] = 1027 // 添加ETH ID
		for _, symbol := range symbols {
			for _, res := range data {
				res := res.(map[string]interface{})
				if symbol == res["symbol"].(string) {
					if _, ok := IdMap[res["symbol"].(string)]; !ok {
						IdMap[res["symbol"].(string)] = res["id"].(float64)
					}
				}
			}
		}

		// get token price
		for key, value := range IdMap {
			id := fmt.Sprintf("%.0f", value)

			i := 1
		CallPriceAPI:
			response, err := http.Get(baseUrl + id + "/?convert=CNY")
			if err != nil {
				// handle error
				i++
				logs.Error("call api failed:", err)
				time.Sleep(5 * time.Second)
				if i > 5 {
					continue
				}
				goto CallPriceAPI
			}

			priceBody, err := ioutil.ReadAll(response.Body)
			if err != nil {
				logs.Error("parse response failed:", err)
				time.Sleep(5 * time.Second)
				continue
			}

			res := make(map[string]interface{})
			err = json.Unmarshal(priceBody, &res)
			if err != nil {
				logs.Error("parse response failed:", err)
				time.Sleep(5 * time.Second)
				continue
			}

			response.Body.Close()
			if res["data"] == nil {
				logs.Error("id not found:", id)
				time.Sleep(5 * time.Second)
				continue
			}
			PriceMap[key] = res["data"].(map[string]interface{})["quotes"].(map[string]interface{})["CNY"].(map[string]interface{})["price"]

			time.Sleep(5 * time.Second)
		}

		logs.Info("tokens price updated.")
		time.Sleep(5 * time.Minute) // update price per 5 minutes
	}

}
